home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Cool Demos, SDKs, & Tools / Demos⁄Tools⁄Offers / Alpha ƒ / Tcl / Menus / electricMenu.tcl < prev    next >
Text File  |  1999-02-25  |  12KB  |  355 lines

  1. ## -*-Tcl-*-
  2.  # ###################################################################
  3.  #    Vince's    Additions -    an extension package for Alpha
  4.  # 
  5.  #    FILE: "electricMenu.tcl"
  6.  #                     created: 8/3/96 {1:34:42 pm}    
  7.  #                  last update: 25/2/1999 {7:57:23 pm}    
  8.  #    Author:    Vince Darley
  9.  #    E-mail:    <darley@fas.harvard.edu>
  10.  #      mail:    Division of    Applied    Sciences, Harvard University
  11.  #            Oxford Street, Cambridge MA    02138, USA
  12.  #       www:    <http://www.fas.harvard.edu/~darley/>
  13.  #    
  14.  #    Handles the electric menu.
  15.  #    
  16.  # ###################################################################
  17.  ##
  18.  
  19. alpha::menu electricMenu 1.3.3 global "•280" {
  20.     # so we don't use the standard proc to build this menu.
  21.     menu::buildProc elec "#"
  22.     namespace eval elec {}
  23. } { 
  24.     elec::rebuildElectricMenu 
  25. } {
  26. } maintainer {
  27.     "Vince Darley" darley@fas.harvard.edu <http://www.fas.harvard.edu/~darley/>
  28. } uninstall this-file help {file "ElecCompletions Help"}
  29.  
  30. alpha::package require elecCompletions 9.0
  31.  
  32. lunion flagPrefs(Electrics) showElectricsInMenu putTemplatesInMainMenu \
  33.   showElectricKeysInMenu addTemplateManipulators 
  34.  
  35. eval lunion elec::MenuTemplates ""
  36. lunion elec::LicenseTemplates \
  37.   "none" "copyrightNotice" "allRightsReserved" "allRightsReservedOrg" \
  38.   "seeFileLicenseTerms" "gnuPublicLicense"
  39.  
  40. # register this proc to be called whenever the mode changes.
  41. hook::register changeMode elec::rebuildElectricMenu
  42. hook::register electricBindings elec::BindingsChanged
  43. # To show mode-dependent electric completions in menu; i.e. include in the
  44. # menu all items which when typed, followed by cmd-Tab, will complete
  45. # into some command, click this box||To remove all mode-dependent
  46. # completions from the electric menu, once you've learnt everything that's
  47. # available, click this box.
  48. newPref flag showElectricsInMenu 1 global elec::clearAndBuildElectricMenu
  49. # To add the list of key-bindings to the bottom of the electric menu (these are
  50. # the items you may edit with 'Config->Special Keys', which are used to
  51. # trigger Completions, Expansions, Template Stop movement etc), click this
  52. # box||To remove the list of key-bindings from the electric menu, once 
  53. # you've learnt them all, click this box.
  54. newPref flag showElectricKeysInMenu 1 global elec::clearAndBuildElectricMenu
  55. # To add a couple of menu items to let you create or delete new templates,
  56. # click this box||To remove the menu items to create/delete templates, click
  57. # this box.
  58. newPref flag addTemplateManipulators 0 global elec::clearAndBuildElectricMenu
  59. # To put all the templates into the main electric menu rather than in a 
  60. # submenu, click this box||To place all templates in a sub-menu of the 
  61. # electric menu, click this box.
  62. newPref flag putTemplatesInMainMenu 0 global elec::clearAndBuildElectricMenu
  63.  
  64. proc elec::BindingsChanged {} {
  65.     global showElectricKeysInMenu
  66.     if {$showElectricKeysInMenu} {elec::clearAndBuildElectricMenu}
  67. }
  68.  
  69. proc elec::getMenuBindings {} {
  70.     global showElectricKeysInMenu keys::specialBindings
  71.     # get menu items which represent the current bindings
  72.     if {$showElectricKeysInMenu} {
  73.     return [menu::bindingsFromArray keys::specialBindings]
  74.     } else {
  75.     return ""
  76.     }
  77. }
  78.  
  79. ## 
  80.  # -------------------------------------------------------------------------
  81.  # 
  82.  # "elec::rebuildElectricMenu" --
  83.  # 
  84.  #  Reasonably clever procedure to construct a Template menu from the
  85.  #  ${mode}electrics array on the fly.  Works with 'ensemble' completions,
  86.  #  putting them in submenus (that's why the code is a little messy; I
  87.  #  couldn't dream up a neater method).
  88.  # -------------------------------------------------------------------------
  89.  ##
  90. proc elec::rebuildElectricMenu {args} {
  91.     set mmode [modeALike]
  92.     if {[cache::exists elecMenu::elec-${mmode}]} {
  93.     cache::read elecMenu::elec-${mmode}
  94.     message ""
  95.     } else {        
  96.     global ${mmode}electrics electricMenu showElectricsInMenu
  97.     
  98.     set m [list Menu -n ${electricMenu} -m -p elec::MenuProc]
  99.     # make the menu of electrics if desired
  100.     if {$showElectricsInMenu && [array exists ${mmode}electrics]} {
  101.         set items [lsort [array names ${mmode}electrics]]
  102.         # remove all contractions
  103.         set items [lremove -all -glob $items "*'*"]
  104.         # remove something else (I've forgotten what!)
  105.         regsub -all { [^ ]*\*[^ ]*} " $items " { } items
  106.         set c [set items]
  107.         while {[regexp {\{(\w+) \w+\}} $c all pref]} {
  108.         set c [string range $c [expr {[string last "\{$pref " $c] +2}] end]
  109.         lappend got $pref
  110.         }
  111.         if {[info exists got]} {
  112.         foreach pref $got {
  113.             regsub "(\{${pref} \\w+\} )+" $items \
  114.               "\{Menu -n \"   ${pref}\" -m -p elec::MenuProc \{\\0\}\} " items
  115.         }
  116.         }    
  117.     } else {
  118.         set items ""
  119.     }
  120.     # make the whole menu
  121.     set items [concat [elec::makeTemplatesMenu $mmode] $items "(-" \
  122.       [elec::getMenuBindings] [list "Add Electric Item"] ]
  123.     global addTemplateManipulators
  124.     if {$addTemplateManipulators} {
  125.         lappend items "Grab Selection" "Insert Old Selection" \
  126.           "Insert In Lines"
  127.     }
  128.     lappend items "Clear Elec Menu Cache"
  129.     lappend m $items
  130.     cache::add elecMenu::elec-${mmode} variable m
  131.     }
  132.     eval $m
  133. }
  134.  
  135. proc elec::clearAndBuildElectricMenu {args} {
  136.     cache::deletePat elecMenu::elec-*
  137.     elec::rebuildElectricMenu
  138. }
  139.  
  140. proc elec::makeTemplatesMenu {mmode} {
  141.     # make the templates submenu
  142.     global ${mmode}Templates elec::MenuTemplates \
  143.       elec::LicenseTemplates menu::additions putTemplatesInMainMenu
  144.     set m ${elec::MenuTemplates}
  145.     if {[info exists ${mmode}Templates]} {
  146.     set m [concat $m [set ${mmode}Templates]]
  147.     }
  148.     set m [lsort $m]
  149.     eval lappend m "(-" [lsort [lremove ${elec::LicenseTemplates} "none"]]
  150.     if {[info exists menu::additions(elec)]} {
  151.     foreach i [set menu::additions(elec)] {
  152.         eval lappend m "(-" [lrange $i 2 end]
  153.     }
  154.     }
  155.     lappend m "(-" "addTemplateItem" "removeTemplateItem"
  156.     if {$putTemplatesInMainMenu} {
  157.     foreach i $m {
  158.         if {[lindex $i 0] == "Menu"} {
  159.         lappend ret $i
  160.         } else {
  161.         lappend ret "[quote::Prettify $i] "
  162.         }
  163.     }
  164.     return $ret
  165.     } else {    
  166.     return [list "Menu -n Templates -p elec::userTemplates [list $m]"]
  167.     }
  168.     
  169. }
  170.  
  171. proc elec::rebuildTemplatesMenu { {mmode ""} } {
  172.     if {$mmode == ""} {set mmode [modeALike]}
  173.     eval [lindex [elec::makeTemplatesMenu $mmode] 0]
  174. }
  175.  
  176. proc elec::userTemplates {menu item} {
  177.     set t [file::$item]    
  178.     if {$t != ""} {
  179.     elec::Insertion $t
  180.     }
  181. }
  182.  
  183. proc elec::MenuProc {menu item} {
  184.     switch -- $item {
  185.     "Next Stop Or Indent" {bind::IndentOrNextstop}
  186.     "Prev Stop" { ring::- }
  187.     "nth Stop" {ring::nth}
  188.     "Complete" {bind::Completion}
  189.     "Complete Or Tab" {bind::TabOrComplete}
  190.     "Expand" {bind::Expansion}
  191.     "Next Stop" {ring::+}
  192.     "Real Tab" {insertActualTab}
  193.     "Add Electric Item" {elec::AddItem}
  194.     "Grab Selection" {elec::GrabSelection}
  195.     "Insert Old Selection" {elec::InsertOldSelection}
  196.     "Insert In Lines" {elec::InsertInLines}
  197.     "Clear All Stops" {ring::clear}
  198.     "Clear Elec Menu Cache" {elec::clearAndBuildElectricMenu}
  199.     default {
  200.         if {[regexp {(.*) $} $item "" item]} {
  201.         set item [join $item ""]
  202.         elec::userTemplates $menu \
  203.           [string tolower [string index $item 0]][string range $item 1 end]
  204.         } else {
  205.         if {[set p [mode::getProc Completion::Insert]] != ""} {
  206.             $p $item
  207.         } else {
  208.             insertText $item
  209.             bind::Completion
  210.         }
  211.         }
  212.     }
  213.     }
  214. }
  215.  
  216. proc elec::AddItem {} {
  217.     global mode
  218.     if {$mode == ""} { beep ; message "No mode set…" ; return }
  219.     global ${mode}electrics
  220.     set e [prompt "Enter the electric item for '$mode' mode:" ""]
  221.     if {$e == ""} {return}
  222.     set default [file::_varValue ${mode}electrics($e)]
  223.     #[file::_getDefault "Do you want to start with this as the template?"]
  224.     set value [getline "Enter the electric extension, using •prompt•, \\r \\\{, \\\} etc" $default]
  225.     if {$value != ""} {
  226.     if {[string length $value] > 210} {
  227.         alertnote "Alpha unfortunately truncates direct entry to about 200 characters, however you can add directly to arrdefs.tcl"
  228.     }
  229.     eval set ${mode}electrics($e) \"$value\"
  230.     addArrDef ${mode}electrics $e [set ${mode}electrics($e)]
  231.     cache::deletePat elecMenu::elec-[modeALike]
  232.     elec::rebuildElectricMenu
  233.     }
  234. }
  235.  
  236. proc file::addTemplateItem {} {
  237.     global elec::MenuTemplates mode
  238.     global ${mode}Templates
  239.     set v elec::MenuTemplates
  240.     set v [expr {$mode != "" && [dialog::yesno \
  241.       "Is this item '$mode' mode-specific (otherwise I'll make it global)?"] \
  242.       ? "${mode}Templates" : "elec::MenuTemplates"}]
  243.     set e [join [prompt "Enter the new template menu item name:" ""] ""]
  244.     if {$e == ""} {return}
  245.     set e [string tolower [string index $e 0]][string range $e 1 end]
  246.     set default [file::_getDefault "Do you want to start with this as the template?" t]
  247.     set t "\r"
  248.     append t "proc file::${e} \{\} \{\r"
  249.     append t "\t# You must fill this in\r"
  250.     append t $default
  251.     append t "\r\r\telec::Insertion \$t\r\}\r"
  252.     addUserLine $t
  253.     lappend $v $e
  254.     lappend modifiedVars $v
  255.     elec::rebuildTemplatesMenu
  256.     regsub -all "\r" $default ";" default
  257.     append default { elec::Insertion $t}
  258.     ;proc file::$e {} $default
  259.     elec::clearAndBuildElectricMenu
  260.     if {[dialog::yesno "I've added a template for the procedure to your 'prefs.tcl'. Do you want to edit it now?"]} {
  261.     global::editPrefsFile
  262.     goto [maxPos]
  263.     }
  264.     return ""
  265. }
  266.  
  267. proc file::removeTemplateItem {} {
  268.     global elec::MenuTemplates mode
  269.     global ${mode}Templates
  270.     global modifiedVars
  271.     set tlist ${elec::MenuTemplates}
  272.     catch {set tlist [concat $tlist [set ${mode}Templates]]}
  273.     set l [listpick -p "Which template shall I permanently remove?" \
  274.       [lsort $tlist]]
  275.     if {[set i [lsearch -exact ${elec::MenuTemplates} $l]] != -1} {
  276.     set elec::MenuTemplates [lreplace ${elec::MenuTemplates} $i $i]
  277.     lappend modifiedVars elec::MenuTemplates
  278.     } else {
  279.     set i [lsearch -exact [set ${mode}Templates] $l]
  280.     set ${mode}Templates [lreplace [set ${mode}Templates] $i $i]
  281.     lappend modifiedVars ${mode}Templates
  282.     }
  283.     elec::rebuildTemplatesMenu
  284.     elec::clearAndBuildElectricMenu
  285.     global::editPrefsFile
  286.     set pat "\rproc\[ \t\]+file::"
  287.     append pat $l
  288.     append pat "\[ \t\]+\{\[ \t\]*\}\[ \t\]\{(\r\[^\}\].*)*\r\}\r"
  289.     while 1 {
  290.     set fpos [search -f 1 -r 1 -n $pat 0]
  291.     if {[llength $fpos] == 0} {
  292.         break
  293.     }
  294.     eval deleteText $fpos
  295.     }
  296.     while 1 {
  297.     set fpos [search -f 1 -r 1 -n "^(\r\r|\n\n)" 0]
  298.     if {[llength $fpos] == 0} {
  299.         break
  300.     }
  301.     eval replaceText $fpos "\r"
  302.     }
  303.     save
  304.     return ""
  305. }
  306.  
  307.  
  308. # procedures below get added to the menu if you set the 'poweruser' flag
  309. # in "elecBindings.tcl".  They make it easy to create large template 
  310. # procedures 
  311. proc elec::GrabSelection {} {
  312.     global __elec::grabbed
  313.     set __elec::grabbed [getSelect]
  314. }
  315.  
  316. proc elec::InsertOldSelection {} {
  317.     global __elec::grabbed
  318.     insertText [quote::Insert [set __elec::grabbed]]
  319. }
  320.  
  321. proc elec::InsertInLines {} {
  322.     global __elec::grabbed
  323.     insertText [elec::_MakeIntoInsertion ${__elec::grabbed}]
  324. }
  325.  
  326. proc elec::_MakeIntoInsertion {t {var "t"}} {
  327.     if {$t == ""} { return $t }
  328.     regsub -all "\n" $t "\r" t
  329.     while 1 {
  330.     set ret [string first "\r" $t]
  331.     if { $ret == -1 } { set ret [string length $t] }
  332.     append b [string range $t 0 $ret]
  333.     if {[string length $b] > 20} {
  334.         while 1 {
  335.         append a "\tappend $var \"[quote::Insert [string range $b 0 59]]\"\r"
  336.         if {[set b [string range $b 60 end]] == ""} {
  337.             break
  338.         }
  339.         }
  340.     }
  341.     set t [string range $t [incr ret] end]
  342.     if {[string length $t] == 0} { 
  343.         if {$b != ""} {
  344.         append a "\tappend $var \"$b\"\r"
  345.         }
  346.         break 
  347.     }
  348.     }
  349.     return $a
  350. }
  351.  
  352.  
  353.  
  354.  
  355.